home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 151-175 / scopedisk159 / parmenu / run.c < prev   
C/C++ Source or Header  |  1995-03-19  |  7KB  |  276 lines

  1. /*
  2.  *    Run.c - Copyright © 1990 by S.R. & P.C.
  3.  *
  4.  *    Created:    16 Jun 1990
  5.  *    Modified:    07 Jul 1990
  6.  *
  7.  *    Make>> make
  8.  */
  9.  
  10. /*
  11. #define DO_ARP_COPIES
  12. #include <libraries/arpbase.h>
  13. #include <functions.h>
  14. #include <exec/memory.h>
  15. #include <workbench/startup.h>
  16. #include <libraries/dosextens.h>
  17. #include <workbench/workbench.h>
  18. */
  19.  
  20. #include <dos_functions.h>
  21. #include <arpdos_pragmas.h>
  22.  
  23. #include "ParM.h"
  24.  
  25. /* Error messages */
  26.  
  27. static const char *ErrNoMem = "Out of memory!";
  28. static const char *NoCmd = "Can't execute command!";
  29. static const char *NoInfo = "Can't open info file!";
  30.  
  31.  
  32. /*****                external functions                    *****/
  33.  
  34. extern char *copystr( char * );
  35. extern void Warn( const char * );
  36.  
  37.  
  38. /*****                 global functions                    *****/
  39.  
  40. void DoExtMenu( USHORT );
  41. void WBFree( struct WBStartup * );
  42.  
  43.  
  44. /*****                 global variables                    *****/
  45.  
  46. extern struct Menu Menu1;
  47. extern struct Process *MyProcess;
  48. extern struct MsgPort *WBReplyPort;
  49. extern short WBCnt;
  50.  
  51.  
  52. /* execute a RB command */
  53.  
  54. static BOOL RunBack(char *cmd, char *args)
  55. {
  56.     BPTR NilFh;
  57.     char buf[256];
  58.     BOOL ret;
  59.  
  60.     SPrintf(buf,"Run >NIL: <NIL: \"%s\" >NIL: <NIL: %s",cmd,args);
  61.     NilFh = Open("NIL:",MODE_NEWFILE);
  62.     if( NilFh ) {
  63.         ret = Execute(buf,NULL,(struct FileHandle *)NilFh);
  64.         Close(NilFh);
  65.     }
  66.     else
  67.         ret = FALSE;
  68.     return ret;
  69. }
  70.  
  71.  
  72. /* execute a CLI command */
  73.  
  74. static void CLIRun(struct Extended_MenuItem *emi)
  75. {
  76.     struct ProcessControlBlock *pcb;
  77.     long CLI;
  78.  
  79.     if( pcb=AllocMem(sizeof(struct ProcessControlBlock),MEMF_PUBLIC|MEMF_CLEAR) ) {
  80.         pcb->pcb_StackSize = emi->emi_Stack;
  81.         pcb->pcb_Pri = emi->emi_Pri;
  82.         pcb->pcb_Console.pcb_ConName = emi->emi_Window;
  83.         pcb->pcb_Control = PRF_STDIO;
  84.         CLI = ASyncRun(emi->emi_Cmd, emi->emi_Args, pcb);
  85.         FreeMem(pcb, sizeof(struct ProcessControlBlock));
  86.         if (CLI<=0) {
  87.             switch( CLI ) {
  88.             case PR_NOFILE :
  89.                 Warn("Command not found");
  90.                 break;
  91.             case PR_NOSTDIO :
  92.                 Warn("Can't open window");
  93.                 break;
  94.             default :
  95.                 Warn(NoCmd);
  96.             }
  97.         }
  98.     }
  99.     else
  100.         Warn(ErrNoMem);
  101. }
  102.  
  103.  
  104. /* procedures to support running WorkBench programs */
  105.  
  106. /*    Free up space used by a workbench startup message.  Called whenever        *
  107.  *    a workbench program replies to the startup message, and whenever        *
  108.  *    WBRun() gets an error                                                     */
  109.  
  110. void WBFree( struct WBStartup *WBStartup )
  111. {
  112.     register BPTR lock;
  113.     register int i;
  114.     register char *cp;
  115.  
  116.     if( WBStartup ) {
  117.         if( WBStartup->sm_ArgList ) {
  118.             for (i=0; i<WBStartup->sm_NumArgs; i++) {
  119.                 if( (lock=WBStartup->sm_ArgList[i].wa_Lock) ) UnLock(lock);
  120.                 if( (cp=WBStartup->sm_ArgList[i].wa_Name) ) FreeMem(cp, strlen(cp)+1);
  121.             }
  122.             FreeMem(WBStartup->sm_ArgList,sizeof(struct WBArg)*WBStartup->sm_NumArgs);
  123.         }
  124.         if( WBStartup->sm_Segment ) UnLoadSeg(WBStartup->sm_Segment);
  125.         if( cp=WBStartup->sm_ToolWindow ) FreeMem(cp, strlen(cp)+1);
  126.         FreeMem( WBStartup , sizeof(struct WBStartup) );
  127.     }
  128. }
  129.  
  130. /*    take the path passed, and split it into a lock and name,
  131.     suitable for putting into a WBArg structure */
  132.  
  133. static void SplitPath( char *path, BPTR *dir_lock, char **name)
  134. {
  135.     register BPTR lock;
  136.  
  137.     *name = BaseName(path);
  138.     lock = Lock(path, ACCESS_READ);
  139.     if( lock ) {
  140.         *dir_lock = (BPTR)ParentDir((struct FileLock *)lock);
  141.         UnLock(lock);
  142.     } else
  143.         *dir_lock = DupLock(MyProcess->pr_CurrentDir);
  144. }
  145.  
  146. /* load and run a workbench program */
  147.  
  148. static void WBRun( char *cmd )
  149. {
  150.     BPTR lock = NULL, OldLock = NULL;
  151.     struct WBStartup *WBStartup = NULL;
  152.     struct DiskObject *disk_object = NULL;
  153.     char *name, buf[128];
  154.     BOOL error = TRUE;    /* assume the worst */
  155.  
  156.     /* allocate the startup message */
  157.     if( !(WBStartup = (struct WBStartup *)AllocMem(sizeof(struct WBStartup),MEMF_PUBLIC|MEMF_CLEAR)) ) {
  158.         Warn(ErrNoMem);
  159.         return;    /* don't go to finish:, nothing allocated yet */
  160.     }
  161.  
  162.     /* find the directory and name of the program to run */
  163.     SplitPath(cmd, &lock, &name);
  164.     if( !lock ) {
  165.         Warn(NoCmd);
  166.         goto finish;
  167.     }
  168.  
  169.     /* try to load in the .info file */
  170.     OldLock = (BPTR)CurrentDir((struct FileLock *)lock);
  171.     if( !(disk_object = GetDiskObject(name)) ) {
  172.         Warn(NoInfo);
  173.         goto finish;
  174.     }
  175.  
  176.     /* allocate the WBArgs - if we are a tool, we allocate one */
  177.     /* of these, else two (one for tool, one for project)      */
  178.  
  179.     if( disk_object->do_Type == WBTOOL ) {
  180.         if( !(WBStartup->sm_ArgList = (struct WBArg *)AllocMem(sizeof(struct WBArg), MEMF_PUBLIC|MEMF_CLEAR)) ) {
  181.             Warn(ErrNoMem);
  182.             goto finish;
  183.         }
  184.         WBStartup->sm_NumArgs = 1;
  185.     } else if( disk_object->do_Type == WBPROJECT ) {
  186.         if( !(WBStartup->sm_ArgList = (struct WBArg *)AllocMem(sizeof(struct WBArg)*2, MEMF_PUBLIC|MEMF_CLEAR)) ) {
  187.             Warn(ErrNoMem);
  188.             goto finish;
  189.         }
  190.         WBStartup->sm_NumArgs = 2;
  191.  
  192.         /* fill in arg #2 with the info we already have */
  193.  
  194.         WBStartup->sm_ArgList[1].wa_Lock = (BPTR)lock;
  195.         WBStartup->sm_ArgList[1].wa_Name = copystr(name);
  196.  
  197.         /* now find the tool */
  198.  
  199.         strcpy( buf , disk_object->do_DefaultTool );
  200.         SplitPath( buf , &lock , &name );
  201.         FreeDiskObject( disk_object );
  202.         CurrentDir( (struct FileLock *)lock );
  203.         if( !(disk_object = GetDiskObject(name)) ) {
  204.             Warn(NoInfo);
  205.             goto finish;
  206.         }
  207.  
  208.         /* we have to have a tool at this point - or else */
  209.  
  210.         if( disk_object->do_Type != WBTOOL ) {
  211.             Warn("Not a tool or project!");
  212.             goto finish;
  213.         }
  214.     }
  215.  
  216.     /* fill in arguments */
  217.  
  218.     WBStartup->sm_ArgList[0].wa_Lock = (BPTR)lock;
  219.     WBStartup->sm_ArgList[0].wa_Name = copystr(name);
  220.  
  221.     /* initialize rest of startup message */
  222.  
  223.     WBStartup->sm_Message.mn_ReplyPort = WBReplyPort;
  224.     WBStartup->sm_Message.mn_Length = sizeof(struct WBStartup);
  225.     WBStartup->sm_Message.mn_Node.ln_Type = NT_MESSAGE;
  226.     WBStartup->sm_ToolWindow = copystr(disk_object->do_ToolWindow);
  227.  
  228.     /* get a decent stack size, there are a few progs that set this to zero */
  229.  
  230.     if( disk_object->do_StackSize < 4000 ) disk_object->do_StackSize = 4000;
  231.  
  232.     /* load in the program */
  233.  
  234.     if( !(WBStartup->sm_Segment = (BPTR)LoadPrg(name)) ) {
  235.         Warn(NoCmd);
  236.         goto finish;
  237.     }
  238.  
  239.     /* create process */
  240.     if( !(WBStartup->sm_Process = (struct MsgPort *)CreateProc(name, 0, WBStartup->sm_Segment, disk_object->do_StackSize)) ) {
  241.         Warn(NoCmd);
  242.         goto finish;
  243.     }
  244.  
  245.     /* everything's ok -- start 'er up */
  246.  
  247.     PutMsg( WBStartup->sm_Process , (struct Message *)WBStartup );
  248.     error = FALSE;
  249.     WBCnt++;    /* keep track of unreplied startup messages */
  250.  
  251. finish:
  252.     if( disk_object ) FreeDiskObject( disk_object );
  253.     CurrentDir( (struct FileLock *)OldLock );
  254.     if( error ) WBFree( WBStartup );
  255. }
  256.  
  257.  
  258. void DoExtMenu( USHORT MenuNum )
  259. {
  260.     struct Extended_MenuItem *Item;
  261.  
  262.     Item = (struct Extended_MenuItem *)ItemAddress( &Menu1 , MenuNum );
  263.     switch( Item->emi_Mode ) {
  264.     case 'r' :
  265.         if( !RunBack(Item->emi_Cmd,Item->emi_Args) ) Warn(NoCmd);
  266.         break;
  267.     case 'c' :
  268.         CLIRun(Item);
  269.         break;
  270.     case 'w' :
  271.         WBRun( Item->emi_Cmd );
  272.         break;
  273.     }
  274. }
  275.  
  276.